﻿using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace Jac.XkDemo.BOS.Business.PlugIn
{
    /// <summary>   
    /// 【服务插件】全事件
    /// 在操作列表进行注册服务插件
    /// </summary>    
    [Description("【服务插件】全事件"), HotUpdate]
    public class AllEventOperationServicePlugIn : Kingdee.BOS.Core.DynamicForm.PlugIn.AbstractOperationServicePlugIn
    {
        #region event        
        /// <summary>        
        /// 选项设置        
        /// 1.在操作服务初始化是执行        
        /// 2.可以对操作的执行参数进行设置，比如是否是否启动事务，是否支持批量处理等      
        /// </summary>        
        /// <param name="e"></param>        
        public override void OnPrepareOperationServiceOption(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.OnPrepareOperationServiceEventArgs e)
        {
            PrintEventInfo("OnPrepareOperationServiceOption", e);
            base.OnPrepareOperationServiceOption(e);
        }

        /// <summary>        
        /// 在执行保存操作前触发        
        /// 1.此时数据包没有填充主键数据        
        /// 2.只有继承了AbstractSave的保存服务才会触发此事件        
        /// </summary>       
        /// <param name="e"></param>        
        public override void BeforeDoSaveExecute(Kingdee.BOS.Core.DynamicForm.PlugIn.BeforeDoSaveExecuteEventArgs e)
        {
            PrintEventInfo("BeforeDoSaveExecute", e);
            base.BeforeDoSaveExecute(e);
        }
        /// <summary>        
        /// 加载指定字段到实体数据包里        
        /// 1.在列表上执行操作时，单据的字段并没有被完全加载。 如果操作插件用到了未被加载的字段，一定会中断。        
        /// 2.本事件允许插件，强制要求加载某些字段，避免中断        
        /// </summary>        
        /// <param name="e"></param>        
        public override void OnPreparePropertys(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.PreparePropertysEventArgs e)
        {
            PrintEventInfo("OnPreparePropertys", e);
            base.OnPreparePropertys(e);
        }
        /// <summary>        
        /// 初始化操作结果        
        /// </summary>        
        /// <param name="result"></param>        
        public override void InitializeOperationResult(Kingdee.BOS.Core.DynamicForm.IOperationResult result)
        {
            PrintEventInfo("InitializeOperationResult", result);
            base.InitializeOperationResult(result);
        }
        /// <summary>        
        /// 添加自定义数据校验器        
        /// 在系统开始执行校验前，插件可以追加自己的校验器进入操作校验器集合        
        /// </summary>        
        /// <param name="e"></param>        
        public override void OnAddValidators(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.AddValidatorsEventArgs e)
        {
            PrintEventInfo("OnAddValidators", e);
            base.OnAddValidators(e);


            //TestValidator validator = new TestValidator();
            //validator.AlwaysValidate = true;
            //validator.EntityKey = "FBillHead";
            //e.Validators.Add(validator);
        }
        /// <summary>        
        /// 执行操作事务前事件，通知插件对要处理的数据进行排序等预处理（事务外触发）       
        /// 1.此事件在操作校验之后、操作实现代码之前执行       
        /// 2.此事件在操作事务之前，即此事件中的数据库处理，不受操作的事务保护       
        /// 3.通常此事件，也可以用来进行数据校验        
        /// </summary>        
        /// <param name="e">e.SelectedRows 准备要处理的扩展实体 e.DataEntitys 处理后的实体</param>        
        public override void BeforeExecuteOperationTransaction(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.BeforeExecuteOperationTransaction e)
        {
            PrintEventInfo("BeforeExecuteOperationTransaction", e);
            base.BeforeExecuteOperationTransaction(e);
        }
        /// <summary>       
        /// 操作事物前事件（事务内触发） 
        /// 1.此事件在操作校验之后        
        /// 2.此事件在操作事务开始之后        
        /// 3.此事件在操作执行代码之前        
        /// 4.此事件中的数据库处理，受操作的事务保护        
        /// 5.通常此事件，可以用来做数据准备，在操作之前，提前写数据到库    
        /// </summary>  
        /// <param name="e"></param>        
        public override void BeginOperationTransaction(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.BeginOperationTransactionArgs e)
        {
            PrintEventInfo("BeginOperationTransaction", e);
            base.BeginOperationTransaction(e);
            //foreach (var model in e.DataEntitys)
            //{
            //    DynamicObjectCollection entryCollection = model["Entity"] as DynamicObjectCollection;
            //    foreach (var obj in entryCollection)
            //    {
            //        var fid = obj["MoEntryId"];
            //        var seq = obj["Seq"];
            //        var sql = "SELECT  t2.FPICKMTRLSTATUS FROM T_PRD_MOENTRY AS t1 LEFT OUTER JOIN T_PRD_MOENTRY_Q AS t2 ON t1.FENTRYID = t2.FENTRYID WHERE t1.FENTRYID = " + fid.ToString();
            //        var pickMtrlStatus = DBServiceHelper.ExecuteScalar(this.Context, sql, "1");
            //        if ("1".Equals(pickMtrlStatus))
            //        {
            //            throw new Exception("领料异常：第" + seq.ToString() + "行 未领料，请联系相关人员领料后再操作\n");
            //        }
            //        if ("2".Equals(pickMtrlStatus))
            //        {
            //            throw new Exception("领料异常：第" + seq.ToString() + "行 部分领料，请联系相关人员领料后再操作\n");
            //        }
            //    }
            //}
        }
        /// <summary>        
        /// 操作事物后事件（事务内触发）        
        /// 1.此事件在操作执行代码之后，操作的内部逻辑已经执行完毕        
        /// 2.此事件在操作事务提交之前        
        /// 3.此事件中的数据库处理，受操作的事务保护        
        /// 4.通常此事件，可以用来做同步数据，如同步生成其他单据，而且需要受事务保护        
        /// </summary>       
        /// <param name="e"></param>        
        public override void EndOperationTransaction(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.EndOperationTransactionArgs e)
        {
            PrintEventInfo("EndOperationTransaction", e);
            base.EndOperationTransaction(e);
            // 自动提交审核
            //var idList = new List<string>();
            //foreach (var billObj in e.DataEntitys)
            //{
            //    var BillId = billObj["Id"].ToString();
            //    idList.Add(BillId);
            //}

            //var formID = this.BusinessInfo.GetForm().Id;
            //var meta = MetaDataServiceHelper.Load(this.Context, formID) as FormMetadata;
            //var subResult = BusinessDataServiceHelper.Submit(this.Context, meta.BusinessInfo, idList.ToArray(), "Submit", null);
            //if (subResult.IsSuccess)
            //{
            //    BusinessDataServiceHelper.Audit(this.Context, meta.BusinessInfo, idList.ToArray(), null);
            //}
        }
        /// <summary>        
        /// 内部事务执行失败后，调用回滚数据事件（事务外触发）        
        /// 1.此事件只有在操作执行过程中发生异常时才触发        
        /// 2.操作异常时，回滚内存中的数据        
        /// 3.避免访问数据库造成事务状态无效的错误        
        /// </summary>        
        /// <param name="e"></param>        
        public override void RollbackData(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.OperationRollbackDataArgs e)
        {
            PrintEventInfo("RollbackData", e);
            base.RollbackData(e);
        }
        /// <summary>       
        /// 执行操作事务后事件，通知插件对象执行其它事务无关的业务逻辑（事务外触发）        
        /// 1.此事件在操作执行后，操作的内部逻辑已经执行完毕；        
        /// 2.此事件在操作事务提交之后；        
        /// 3.此事件中的数据库处理，不受操作的事务保护        
        /// 4.通常此事件，也可以做同步数据，但是此同步数据的成功与否，不需影响操作        
        /// </summary>        
        /// <param name="e"></param>        
        public override void AfterExecuteOperationTransaction(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.AfterExecuteOperationTransaction e)
        {
            PrintEventInfo("AfterExecuteOperationTransaction", e);
            base.AfterExecuteOperationTransaction(e);
        }
        #endregion

        #region private method   

        /// <summary>       
        /// 事件执行次数计数器     
        /// </summary>        
        private int counter;
        /// <summary>       
        /// 事件执行次数计数器        
        /// </summary>        
        private int Counter { get { return ++counter; } }

        /// <summary>      
        /// 输出事件执行日志    
        /// </summary>        
        /// <param name="eventName">事件名称</param>       
        /// <param name="args">事件参数</param>        
        private void PrintEventInfo(string eventName, params object[] args)
        {
            var formId = GetFormId();
            var parameters = string.Empty;
            try
            {
                parameters = Newtonsoft.Json.JsonConvert.SerializeObject(args);
            }
            catch { }
            var log = string.Format("序号:{0},执行时间:{1},表单Id:{2},事件名称:{3},事件参数:{4}", Counter, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), formId, eventName, parameters);
            System.Diagnostics.Debug.Print(log);
            Kingdee.BOS.Log.Logger.Error("EVENT", log, null);
        }

        /// <summary>      
        /// 获取业务对象标识     
        /// </summary>       
        /// <returns></returns>       
        private string GetFormId()
        {
            return this.BusinessInfo.GetForm().Id;
        }
        #endregion
    }
}


